package com.neu.gulimall.order;

import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 使用rabbitMQ的步骤：
 *  1、引入amqp场景: RabbitAutoConfiguration 就会自动生效
 *         <dependency>
 *             <groupId>org.springframework.boot</groupId>
 *             <artifactId>spring-boot-starter-amqp</artifactId>
 *         </dependency>
 *  2、给容器中自动配置了：RabbitMessagingTemplate、RabbitTemplate、amqpAdmin、CachingConnectionFactory
 *          rabbitMQ的相关属性配置都在这个类中：
 *              @ConfigurationProperties(
 *                       prefix = "spring.rabbitmq"
 *                      )
 *              public class RabbitProperties
 *
 *  3、在配置文件中配置 rabbitMQ 的属性信息
 *        rabbitmq:
 *     host: 127.0.0.1
 *     port: 5672
 *     virtual-host: /
 *  4、给启动类添加注解 @EnableRabbit
 *  5、监听消息，使用 @RabbitListener 注解， 必须要有 @EnableRabbit 注解
 *          @RabbitListener：类 + 方法上 （监听哪些队列即可）
 *          @RabbitHandler： 标在方法上 （重载区分不同类型的消息）
 *  6、本地事务失效问题：
 *      同一个对象内，事务方法互调默认失效， 原因是 绕过了代理对象， 事务是使用代理对象来控制的
 *      解决方法： 使用代理对象来调用事务方法：
 *          1、引入 spring-boot-starter-aop： 这个依赖里有 aspectj
 *          2、使用 @EnableAspectJAutoProxy 注解，开启 aspectj 动态代理功能 以后的动态代理都是aspectj创建的（即使没有接口，也可以创建动态代理）
 *              exposeProxy = true  设置为 对外暴露代理对象
 *          3、本类中互相调用使用调用对象
 *              OrderServiceImpl orderService = (OrderServiceImpl) AopContext.currentProxy();
 *              orderService.b();
 *              orderService.c();
 *
 *   7、使用seata来控制分布式事务
 *      1、每一个微服务对应的数据库中创建回滚事务表 undo_log
 *      2、安装事务协调器 ： seata-server ：  https://github.com/seata/seata/releases
 *      3、整合步骤：
 *          1、导入依赖  seata版本1.4.2
 *               <dependency>
 *             <groupId>com.alibaba.cloud</groupId>
 *             <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
 *             <version>2.1.0.RELEASE</version>
 *             <exclusions>
 *                 <exclusion>
 *                     <groupId>io.seata</groupId>
 *                     <artifactId>seata-spring-boot-starter</artifactId>
 *                 </exclusion>
 *             </exclusions>
 *         </dependency>
 *
 *         <dependency>
 *             <groupId>io.seata</groupId>
 *             <artifactId>seata-spring-boot-starter</artifactId>
 *             <version>1.4.2</version>
 *         </dependency>
 *         2、解压并启动 seata-server
 *              registry.conf : 注册中心配置  修改registry type=nacos
 *         3、所有想要用到分布式事务的微服务使用 seata DataSourceProxy 代理自己的数据源
 *         4、每个微服务都必须导入
 *         5、启动测试分布式事务
 *         6、给分布式大事务入口标注 @GlobalTransactional
 *         7、给每个远程的小事务用 @Transactional
 *@EnableAutoDataSourceProxy
 *
 */

@EnableAspectJAutoProxy(exposeProxy = true)
@EnableFeignClients(basePackages = "com.neu.gulimall.order.feign")
@EnableRedisHttpSession
@EnableDiscoveryClient
@EnableRabbit
@SpringBootApplication
public class GulimallOrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallOrderApplication.class, args);
    }

}
